package models;

import global.ConfigData;

import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

//import sun.font.CreatedFontTracker;

import lib.Field;
import models.Person;
import models.Publication;
import lib.persistence.NotFoundException;
import lib.persistence.commands.GetRow;
import lib.persistence.commands.GetModelsByField;

public class Publication extends ModelAbstract implements Serializable
{
	/*
	PK - publication_id: Integer	
	Creation Date: Integer/Date	
	Created by: Person	
	Publication Title: String	
	Located at: String	
	Publication Date: Integer/Date	
	Publication Authors (Alphabetical): List<Persons>	
	Description: String
	 */

	private int publicationID;
	
	// subject to removal
	private Date creationDate;
	private Person creator;
	//

	private String title;
	public String location;
	private Date publicationDate;
	private ArrayList<Person> authors;
	private String description;
	private Project project;
	// main CTOR

	public Publication(int publicationID, Date creationDate,
			Person creator, String title, String location,
			Date publicationDate, ArrayList<Person> authors,
			String description) {
		super();
		this.publicationID = publicationID;
		this.creationDate = creationDate;
		this.creator = creator;
		this.title = title;
		this.location = location;
		this.publicationDate = publicationDate;
		this.authors = authors;
		this.description = description;
	}

	public Publication() {
		// TODO Auto-generated constructor stub
	}

	public int getPublicationID() {
		return publicationID;
	}
	public void setPublicationID(int publicationID) {
		this.publicationID = publicationID;
	}
	public Date getCreationDate() {
		return creationDate;
	}
	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}
	public Person getCreator() {
		return creator;
	}
	public void setCreator(Person creator) {
		this.creator = creator;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getLocation() {
		return location;
	}
	public void setLocation(String location) {
		this.location = location;
	}
	public Date getPublicationDate() {
		return publicationDate;
	}
	public void setPublicationDate(Date publicationDate) {
		this.publicationDate = publicationDate;
	}
	public void setPublicationDate(String publicationDate) {
		SimpleDateFormat d = new SimpleDateFormat("MM/dd/yy");
		try {
			this.publicationDate = d.parse(publicationDate);
		} catch (ParseException e) {
		}

	}
	public void setCreatedAt(String createdAt) {
		SimpleDateFormat d = new SimpleDateFormat("MM/dd/yy");
		try {
			this.creationDate = d.parse(createdAt);
		} catch (ParseException e) {
		}

	}
	public ArrayList<Person> getAuthors() {
		return authors;
	}
	public void setAuthors(ArrayList<Person> authors) {
		this.authors = authors;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}

	public boolean equals(Publication o)
	{
		if (this.publicationID != o.publicationID)
			return false;
		if (!this.creationDate.equals(o.creationDate))
			return false;
		if (!this.creator.equals(o.creator))
			return false;
		if (!this.title.equals(o.title))
			return false;
		if(!this.publicationDate.equals(o.publicationDate))
			return false;
		if (!this.description.equals(o.description))
			return false;

		if (this.authors != null && o.authors != null)
		{

			Iterator<Person> iterator = o.authors.iterator();
			Iterator<Person> thisIterator = this.authors.iterator();

			if (iterator == null)
				return false;

			while (iterator.hasNext() && thisIterator.hasNext())
			{
				if (!iterator.next().equals(thisIterator.next()))
					return false;
			}

			if (iterator.hasNext() || thisIterator.hasNext())
				return false;
		}
		else
			if (this.authors != null || o.authors != null)
				return false;

		return true;
	}

	@Override
	public int getId() {
	    // TODO Auto-generated method stub
	    return id;
	}

	@Override
	protected ArrayList<Field> getSqlReadyFields() {
	   
		ArrayList<Field> al = new ArrayList<Field>();
		Field f;
		
		// add blob
		f = new Field();
		al.add(f.setName("obj").setType("blob").setObjValue(this));
		
		
		//add creator
		if (creator != null)
		{		
			f = new Field();
			al.add(f.setName("createdBy").setType("integer").setValue("" + creator.getId()));
		}
		// add title
		f = new Field();
		al.add(f.setName("title").setType("string").setValue(this.getTitle()));
		
		// add location
		f = new Field();
		al.add(f.setName("location").setType("string").setValue(this.getLocation()));
		
		// add date
		f = new Field();
		al.add(f.setName("pubdate").setType("date").setObjValue(this.getPublicationDate()));
		
		if (this.project != null)
		{
			f = new Field();
			al.add(f.setName("project_id").setType("Integer").setValue(""+this.project.getId()));		
		}

		String authorIds = "";
		for (int i = 0 ; i < authors.size() ; i++)
		{
			authorIds = authorIds.concat(""+authors.get(i).getId());
			if (i < authors.size() - 1)
				authorIds = authorIds.concat(",");
		}
	    f = new Field();
	    al.add(f.setName("author_ids").setType("string").setValue(authorIds));
		
	    return al;
	}

	@Override
	protected String getTableName() {
	    return ConfigData.PUBLICATION_TABLE;
	}

	@Override
	public void setId(int id) {
	    
		this.id = id;
	    
	}
	public void setId(String id)
	{
		setId(Integer.parseInt(id));
	}
	public void setAuthorIds(String authorIds)
	{
		if (authorIds == null || authorIds.equalsIgnoreCase(""))
			return;
		List<Person> authors = new ArrayList<Person>();
        String[] splitArray = authorIds.split("\\,");
        for (String id: splitArray) {
        	try {
				Person p = Person.find(Integer.parseInt(id));
				authors.add(p);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
        this.authors = (ArrayList<Person>) authors;
	}
	public void setCreatedBy(String personId)
	{
		try {
			this.setCreatedBy(Person.find(Integer.parseInt(personId)));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
    public void setCreatedBy(Person creator) {
    	this.creator = creator;
     }
    public void setProjectId(String project_id) {
    	try {
			setProject(Project.find(Integer.parseInt(project_id)));
		} catch (Exception e) {
			e.printStackTrace();
		}
    }

	private void setProject(Project project) {
		this.project = project;
	}

	private Project getProject() {
		return project;
	}
	
	public static Publication find(int id) throws NotFoundException, SQLException, IOException, ClassNotFoundException 
	{
		GetRow gr = new GetRow();
		Publication p = (Publication) gr.findObjectById(id, ConfigData.PUBLICATION_TABLE, "obj");
		
		int creatorId = gr.findIntById(id, ConfigData.PUBLICATION_TABLE, "createdBy");
		p.setCreatedBy((Person) gr.findObjectById(creatorId, ConfigData.PERSON_TABLE, "obj"));
		
		String authorIds = (String) gr.findObjectById(id, ConfigData.PUBLICATION_TABLE, "AuthorIds");
		p.setAuthorIds(authorIds);
		
		int projectId = gr.findIntById(id, ConfigData.PUBLICATION_TABLE, "project_id");
		p.setProject((Project) gr.findObjectById(projectId, ConfigData.PUBLICATION_TABLE, "obj"));
		
		return p;
	}
}